package com.alks.function.service.impl;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.UserInfoUtil;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.entity.data.entity.PcBeforeLastTime;
import com.alks.entity.data.entity.PcProdStatus2;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.dto.PcProdStatus2CountDto;
import com.alks.function.data.dto.PcProdStatus2Dto;
import com.alks.function.data.request.PcProdStatus2Request;
import com.alks.function.data.request.chengKong.LotNoToStyleRequest;
import com.alks.function.mapper.PcProdStatus2Mapper;
import com.alks.function.service.PcProdStatus2Service;
import com.alks.function.service.impl.asyncImpl.PcProdStatus2AsyncService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PcProdStatus2ServiceImpl extends ServiceImpl<PcProdStatus2Mapper, PcProdStatus2> implements PcProdStatus2Service {

    @Autowired
    private PcProdStatus2Mapper pcProdStatus2Mapper;

    @Autowired
    PcProdStatus2AsyncService status2Service;

    /**
     * 生产动态查询
     *
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getProductionDynamicQueryInfo(PcProdStatus2Request request) {
        String companyId = UserIdThread.get().getCompanyId();
        request.setCompanyId(companyId);
        //生产动态明细
        List<PcProdStatus2Dto> queryData = pcProdStatus2Mapper.getProductionDynamicQueryData(request);

        //获取条数
        PageInfo list = new PageInfo(queryData);

        //统计订单预补数量
        PcProdStatus2CountDto count = pcProdStatus2Mapper.getCount(request);

        Map map = new HashMap();
        map.put("queryData", queryData);
        map.put("total", list.getTotal());
        map.put("count", count);

        return ResponseInfo.ok(map);
    }

    /**
     * 时程门槛定义
     *
     * @return
     */
    @Override
    public ResponseInfo getTimeDeFine() {
        return ResponseInfo.ok(pcProdStatus2Mapper.getTimeDeFine(UserIdThread.get().getCompanyId()));
    }

    /**
     * 修改时程门槛定义
     *
     * @param pcBeforeLastTime
     * @return
     */
    @Override
    public ResponseInfo updateTimeDeFine(PcBeforeLastTime pcBeforeLastTime) {
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        pcBeforeLastTime.setCompanyId(userInfo.getCompanyId());
        pcBeforeLastTime.setSysDate(new Date());
        pcBeforeLastTime.setUserId(userInfo.getLoginName());
        pcProdStatus2Mapper.updateByID(pcBeforeLastTime);
        return ResponseInfo.ok();
    }

    @Override
    public List<PcProdStatus2Dto> export(PcProdStatus2Request request) {
        String companyId = UserIdThread.get().getCompanyId();
        request.setCompanyId(companyId);
        /*获取数据*/
        List<PcProdStatus2Dto> queryData = pcProdStatus2Mapper.getProductionDynamicQueryData(request);
        int seqNo = 1;
        for (PcProdStatus2Dto queryDatum : queryData) {
            queryDatum.setSeqNo(seqNo);
            seqNo++;
        }
        Map<String, List<PcProdStatus2Dto>> deliveryMap = queryData.stream()
                .collect(Collectors.groupingBy(
                        a -> a.getDeliveryDate().format(DateTimeFormatter.ofPattern("MM"))));
        List<PcProdStatus2Dto> dtoList = new ArrayList<>();
        deliveryMap.forEach((key, value) -> {
                    dtoList.addAll(value);
                    PcProdStatus2Dto dto = new PcProdStatus2Dto();
                    dto.setCustom(key + "月合计：");
                    dto.setOrderQty(value.stream()
                            .map(PcProdStatus2Dto::getOrderQty)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setCutShort(value.stream()
                            .map(PcProdStatus2Dto::getCutShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setSoleShort(value.stream()
                            .map(PcProdStatus2Dto::getSoleShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setStitchShort(value.stream()
                            .map(PcProdStatus2Dto::getStitchShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setHfShort(value.stream()
                            .map(PcProdStatus2Dto::getHfShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setLastShort(value.stream()
                            .map(PcProdStatus2Dto::getLastShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setSoleShort2(value.stream()
                            .map(PcProdStatus2Dto::getSoleShort2)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setFinishShort(value.stream()
                            .map(PcProdStatus2Dto::getFinishShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dto.setPartShort(value.stream()
                            .map(PcProdStatus2Dto::getPartShort)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    dtoList.add(dto);
                }
        );
        return dtoList;
    }

    /**
     * 生成生产动态表
     * @param companyId
     * @param name
     * @return
     */
    @Override
    public ResponseInfo GenerateProductionDynamics(String companyId, String name) {
        status2Service.GenerateProductionDynamics(companyId, name);
        return ResponseInfo.ok("操作成功,系统处理数据中,请稍后查看!");
    }

    /**
     * 标记指令已结束
     * @param lotNo
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo labelFlag(String lotNo) {
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcProdStatus2> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcProdStatus2::getLotNo,lotNo)
                        .eq(PcProdStatus2::getCompanyId,companyId);
        PcProdStatus2 pcProdStatus2 = pcProdStatus2Mapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcProdStatus2)){
            return ResponseInfo.error("该指令不在生产动态表中!");
        }
        if ("Y".equals(pcProdStatus2.getLotFlag())){
            return ResponseInfo.warn("该指令已标记结束!");
        }
        pcProdStatus2Mapper.addPcLotHandEnd(companyId,lotNo);
        LambdaUpdateWrapper<PcProdStatus2> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PcProdStatus2::getLotNo,lotNo)
                .eq(PcProdStatus2::getCompanyId,companyId)
                .set(PcProdStatus2::getLotFlag,"Y");
        pcProdStatus2Mapper.update(null,updateWrapper);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 取消标记
     * @param lotNo
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo cancelLabelFlag(String lotNo) {
        String companyId = UserIdThread.get().getCompanyId();
        LambdaQueryWrapper<PcProdStatus2> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcProdStatus2::getLotNo,lotNo)
                .eq(PcProdStatus2::getCompanyId,companyId);
        PcProdStatus2 pcProdStatus2 = pcProdStatus2Mapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(pcProdStatus2)){
            return ResponseInfo.error("该指令不在生产动态表中!");
        }
        if ("Y".equals(pcProdStatus2.getLotFlag())){
            return ResponseInfo.warn("该指令已取消标注!");
        }
        pcProdStatus2Mapper.delPcLotHandEnd(companyId,lotNo);
        LambdaUpdateWrapper<PcProdStatus2> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PcProdStatus2::getLotNo,lotNo)
                .eq(PcProdStatus2::getCompanyId,companyId)
                .set(PcProdStatus2::getLotFlag,"N");
        pcProdStatus2Mapper.update(null,updateWrapper);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 返回核算时间
     * @return
     */
    @Override
    public ResponseInfo ReturnTime() {
        String date = pcProdStatus2Mapper.ReturnTime(UserIdThread.get().getCompanyId());
        return ResponseInfo.ok(date,"成功！");
    }

    /**
     *  查询标注结束指令
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getLotNos(LotNoToStyleRequest request) {
        request.setCompanyId(UserIdThread.get().getCompanyId());
        List<String> lotNoList = pcProdStatus2Mapper.getLotNoList(request);
        HashMap<Object, Object> map = new HashMap<>();
        PageInfo list = new PageInfo(lotNoList);
        map.put("list",lotNoList);
        map.put("total",list.getTotal());
        return ResponseInfo.ok(map);
    }
}
